#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#ifndef NDEBUG	//!< I think that in this case the preprocessor debug-block isn't really useful, \
if the program is spec. designed to HAVE an interface, but I'll use it anyway.
	#define DOUT( toprint ) printf( "\n# " toprint )        //!< Debug output, prints a plain text line preceded by #
	#define DPUT( toput , x ) printf( "\n# " toput , x )	//!< Debug put, a DOUT with a single variable inside
	#define DLN                                             //!< Debug line, doesn't exist in release( with NDEBUG defined )
	#define DPUTCLOSURE	DOUT("=============================================================================");\
			DPUT("FILE: %s", __FILE__ );\
			DPUT("COMPILATION DATE: %s", __DATE__ );\
			DPUT("COMPILATION TIME: %s\n", __TIME__ )//!< Put a closing statement, complete with datestamp and finename.
#else
	#define DOUT
	#define DPUT
	#define DLN if(0)
	#define DPUTCLOSURE
#endif

const int CTRL_GROUND_STATE = -1;

typedef struct stk_i { //!< For C-style structs
	long num;
	int* data;
	int* end;
} stk_i;

int Stk_push( stk_i&, int );	//.push and .pop return controller-integers;
int Stk_pop( stk_i&, int* );	//.pop puts the extracted value into given integer
int Stk_bpush( stk_i& );		//Also, reference-passing, 'cause I'd forgotten all about that we need to change stuff
int Stk_OK( stk_i );
int STK_MT( stk_i );

int main()
{
	DOUT( "\tThis here is the integer-based stack operator program." );
	DOUT( "Please enter the number which corresponds to your desired operation:" );
	DOUT( "1. Create a stack." );
	DOUT( "2. Push a single number into the stack" );
	DOUT( "3. Batch-push numbers (auto-allocates required memory if needed)" );
	DOUT( "4. Pop a number" );
	DOUT( "5. Stack integrity check" );
	DOUT( " >" );

	int ctrl = CTRL_GROUND_STATE,	//!< ctrl ACTUALLY doing anything ain't implemented
	chk = scanf_s( "%d", &ctrl ); //!< Scanf_s is to combat compilation errors in VS2012
	assert( ( "A number was entered",
			chk == 1 ) );

	stk_i Stack = {0, NULL, NULL};


	DOUT( "Enter the amount of numbers you'd want to initialize the stack with now:" );
	DOUT( "> " );

	chk = scanf_s( "%ld", &Stack.num );
	assert( ( "A number of elems to add was entered",
	          chk == 1 ) );

	Stack.data	= ( int* ) calloc( Stack.num, sizeof( Stack.data ) );
	Stack.end	= Stack.data; //!< So yeah, I'll take end corresponding to amount of successfully pushed numbers.

	DOUT( "So then, enter those numbers:" );
	DOUT( "> " );

	for( long int i = 0; i < Stack.num;
	        i++, Stack.end++ ) {
		chk = scanf_s( "%d", &( Stack.data[i] ) );

		if( chk != 1 ) {
			printf( "Incorrect input to stack at %ld-th position", ( i + 1 ) );
			return 1;
		}
	}

	DPUTCLOSURE;
	return 0;
}

int Stk_OK( stk_i s )
{
	return 1;
}

int Stk_MT( stk_i s )
{
	if( s.data == s.end )
		return 1;
	else
		return 0;
}

int Stk_push( stk_i &s, int toadd )
{
	if( Stk_OK( s ) ) {
		s.data[s.num] = toadd;
		s.end++;
		s.num++;
		return 1;
	} else
		return 0;
}

int Stk_pop( stk_i &s, int out[] )
{
	if( Stk_OK( s ) ) {
		*out = *( s.end );
		s.end--;
		return 1;
	} else
		return 0;
}

int Stk_bpush( stk_i &s ) //This one features its own interface. Incosnsistene with other funcs, consistent with the initialize-and-fill
{
	DOUT( "Enter the amount of numbers you'd want to batch-push into the stack now:" );
	DOUT( "> " );

	int deltanum = 0,
	    chk = scanf_s( "%ld", &deltanum );
	assert( ( "A number of elems to add was entered",
	          chk == 1 ) );

	s.num	+= deltanum;
	s.data	= ( int* ) realloc( s.data, s.num );
	s.end	= s.data + s.num;				//Pointer arithmetic, re-find *end

	DOUT( "So then, enter those numbers:" );
	DOUT( "> " );

	for( long int i = 0; i < deltanum; i++, s.end++ ) {
		chk = scanf_s( "%d", &( s.data[i] ) );

		if( chk != 1 ) {
			printf( "Incorrect input to stack at %ld-th position",
			        ( i + 1 + s.num ) );
			return 0;
		}
	}

	return 1;
}
